--函数！

--用法：local HX = require "packages/huixiangkill/hxfs"
--如HX.DrawCardFromPile(player.room, player, baguan2022.name, 2)

local hxfs = {}


--选择一种类型的牌，从牌堆中依次摸任意张
---@param room Room @ 房间
---@param player ServerPlayer @ 摸牌的角色
---@param Skill string @ 技能名
---@param num integer @ 要摸的数量
function hxfs.DrawCardFromPile(room, player, Skill, num)
    local choice = room:askToChoice(player,{
        choices = {"基本牌", "锦囊牌", "装备牌"},
        skill_name = Skill,
        prompt = "请选择摸的牌的类型",
    })
    local cardType = ""
    if choice == "基本牌" then
        cardType = "basic"
    elseif choice == "锦囊牌" then
        cardType = "trick"
    elseif choice == "装备牌" then
        cardType = "equip"
    else
        return -- 如果选择无效，直接返回
    end
    for i = 1, num do
      local cards = room:getCardsFromPileByRule(".|.|.|.|.|" .. cardType)
      if #cards > 0 then
        room:obtainCard(player, cards[1], false, fk.ReasonDraw, player, Skill)
      end
    end
end


---通过仅改变武将改变武将图像
---@param room Room @ 房间
---@param player ServerPlayer 改变图像的角色
---@param old string   需要改变的武将名
---@param new string   改变后的武将名
function hxfs.ChangeGeneral(room, player, old, new)
  if player.deputyGeneral == old or player.general == old then
    if player.deputyGeneral == old then
      player.deputyGeneral = new
      room:broadcastProperty(player, "deputyGeneral")
    elseif player.general == old then
      player.general = new
      room:broadcastProperty(player, "general")
    end
  else
    player.general = new
    room:broadcastProperty(player, "general")
  end
end

---设置一名角色所有技能的已发动次数（发送战报）
---@param room Room @ 房间
---@param player ServerPlayer @ 角色
---@param times integer @ 要设置的次数
function hxfs.SetSkillsTimes(room, player, times)
  local skills = table.simpleClone(Fk.generals[player.general]:getSkillNameList(true))
  if player.deputyGeneral ~= "" then
    table.insertTableIfNeed(skills, Fk.generals[player.deputyGeneral]:getSkillNameList(true))
  end
  skills = table.filter(skills, function(s) return player:hasSkill(s) end)
  if #skills > 0 then
    for _, s in ipairs(skills) do
      player:setSkillUseHistory(s, times, Player.HistoryPhase)
      player:setSkillUseHistory(s, times, Player.HistoryTurn)
      player:setSkillUseHistory(s, times, Player.HistoryRound)
      player:setSkillUseHistory(s, times, Player.HistoryGame)
    end
    room:sendLog{
      type = "%from 所有技能的发动次数已被设置为 "..times.." 次！",
      from = player.id,
      --arg = s,
    }
  end
end

---设置一名角色的一个技能的已发动次数（发送战报）
---@param room Room @ 房间
---@param player ServerPlayer @ 角色
---@param skill string @ 技能名
---@param times integer @ 要设置的次数
function hxfs.SetTheSkillTimes(room, player, skill, times)
  player:setSkillUseHistory(skill, times, Player.HistoryPhase)
  player:setSkillUseHistory(skill, times, Player.HistoryTurn)
  player:setSkillUseHistory(skill, times, Player.HistoryRound)
  player:setSkillUseHistory(skill, times, Player.HistoryGame)
  room:sendLog{
    type = "%from 的【"..Fk:translate(skill).."】的发动次数已被设置为 "..times.." 次。",
    from = player.id,
    --arg = s,
  }
end

---令一名角色将手牌数摸至或弃至对应值
---@param room Room @ 房间
---@param player ServerPlayer @ 角色
---@param num integer @ 值
---@param Skill string @ 技能名
function hxfs.SetPlayerHandNum(room, player, num, Skill)
  local n = player:getHandcardNum()
  if n < num then
    player:drawCards(num-n, Skill)
  elseif n > num then
    room:askToDiscard(player, {
      min_num = n-num,
      max_num = n-num,
      include_equip = false,
      skill_name = Skill,
      cancelable = false,
    })
  end
end


---令一名角色从牌堆中获得一张指定牌名的牌（牌堆没有会从弃牌堆中获得）
---@param room Room @ 房间
---@param player ServerPlayer @ 角色
---@param name string @ 牌名
---@param Skill string @ 技能名
---@param moveMark? table|string @ 移动后自动赋予标记，格式：{标记名(支持-inarea后缀，移出值代表区域后清除), 值}
function hxfs.GetCardFromPile(room, player, name, Skill, moveMark)
  local card1 = table.filter(room.draw_pile, function(id)
    return Fk:getCardById(id).trueName == name
  end)
  if #card1 > 0 then
    local card = Fk:getCardById(table.random(card1))
    room:obtainCard(player, card, false, fk.ReasonPrey, player, Skill, moveMark)
  else
    local card1_2 = table.filter(room.discard_pile, function(id)
      return Fk:getCardById(id).trueName == name
    end)
    if #card1_2 > 0 then
      local card = Fk:getCardById(table.random(card1_2))
      room:obtainCard(player, card, false, fk.ReasonPrey, player, Skill, moveMark)
    end
  end
end


---令一名角色从牌堆中获得一张指定点数的牌（牌堆没有会从弃牌堆中获得）
---@param room Room @ 房间
---@param player ServerPlayer @ 角色
---@param number string @ 点数
---@param Skill string @ 技能名
function hxfs.GetNumberCardFromPile(room, player, number, Skill)
  local card1 = table.filter(room.draw_pile, function(id)
    return Fk:getCardById(id).number == number
  end)
  if #card1 > 0 then
    local card = Fk:getCardById(table.random(card1))
    room:obtainCard(player, card, false, fk.ReasonPrey, player, Skill)
  else
    local card1_2 = table.filter(room.discard_pile, function(id)
      return Fk:getCardById(id).number == number
    end)
    if #card1_2 > 0 then
      local card = Fk:getCardById(table.random(card1_2))
      room:obtainCard(player, card, false, fk.ReasonPrey, player, Skill)
    end
  end
end


---令一名角色从牌堆中获得一张指定花色的牌（牌堆没有会从弃牌堆中获得）
---@param room Room @ 房间
---@param player ServerPlayer @ 角色
---@param suit integer @ 花色
---@param Skill string @ 技能名
function hxfs.GetSuitCardFromPile(room, player, suit, Skill)
  local card1 = table.filter(room.draw_pile, function(id)
    return Fk:getCardById(id).suit == suit
  end)
  if #card1 > 0 then
    local card = Fk:getCardById(table.random(card1))
    room:obtainCard(player, card, false, fk.ReasonPrey, player, Skill)
  else
    local card1_2 = table.filter(room.discard_pile, function(id)
      return Fk:getCardById(id).suit == suit
    end)
    if #card1_2 > 0 then
      local card = Fk:getCardById(table.random(card1_2))
      room:obtainCard(player, card, false, fk.ReasonPrey, player, Skill)
    end
  end
end


---令一名角色从牌堆中获得一张指定类型的牌（牌堆没有会从弃牌堆中获得）
---@param room Room @ 房间
---@param player ServerPlayer @ 角色
---@param type string @ 类型
---@param Skill string @ 技能名
function hxfs.GetTypeCardFromPile(room, player, type, Skill)
  local card1 = table.filter(room.draw_pile, function(id)
    return Fk:getCardById(id).type == type
  end)
  if #card1 > 0 then
    local card = Fk:getCardById(table.random(card1))
    room:obtainCard(player, card, false, fk.ReasonPrey, player, Skill)
  else
    local card1_2 = table.filter(room.discard_pile, function(id)
      return Fk:getCardById(id).type == type
    end)
    if #card1_2 > 0 then
      local card = Fk:getCardById(table.random(card1_2))
      room:obtainCard(player, card, false, fk.ReasonPrey, player, Skill)
    end
  end
end


---实现租号技能的主要逻辑，技能描述如下：
---每轮开始时，你可以展示至多x张武将牌，若如此做，你根据下面的关键词依次选择这些武将牌："..
---"<br/>①“摸牌”；"..
---"<br/>②“视为”；"..
---"<br/>③“伤害”。"..
---"<br/>若被选武将的某个技能的描述中包含对应关键词，<br/>则你本轮获得此技能；若被选武将无此类技能，你减1点体力上限。"..
---"（x为你的体力上限且至少为3，至多为100）"
---@param room Room @ 房间
---@param player ServerPlayer @ 角色
---@param pattern1 string @ 租号词条1
---@param pattern2 string @ 租号词条2
---@param pattern3 string @ 租号词条3
---@param Skill string @ 技能名
---@param MIN? integer @ x的最小值，至少为3
function hxfs.ZuHaoSelect(room, player, pattern1,pattern2,pattern3, Skill, MIN)
  local choices = {}
  local number
  --接下来的11行，控制展示武将的最大值，最小值的控制则直接写在了可选武将初始化部分
  local max = player.maxHp
  if MIN then
    if max < MIN then
      max = MIN
    end
  end
  for i = 1, max do
    if i <= 100 then  --最多100个，太多了会把服务器搞崩（100上限以上的你们输了）
      table.insert(choices, tostring(i))
    end
  end
  if player.id <= 0 then return false end  --排除人机
  if #choices > 2 then
    --定义类型解决黄色波浪线
    number = tonumber(room:askToChoice(player,{choices = choices, skill_name = Skill ,cancelable = false, prompt = "请选择至多"..#choices.."张武将牌展示"})) ---@type integer
  else  --吃到保底了就不选了
    number = #choices
  end
  --232到247行，抄来的筛选武将的方法，筛进来了同名武将，正合租号技能的要求
  local existingGenerals = {}
  table.forEach(room.players, function(p)
    table.insertTable(existingGenerals, {p.general, p.deputyGeneral})
  end)
  local allgenerals, same_generals = {}, {}
  for _, general_name in ipairs(room.general_pile) do   --（超绝for循环要开始了）
    same_generals = Fk:getSameGenerals(general_name)
    table.insert(same_generals, general_name)
    same_generals = table.filter(same_generals, function (g_name)
      local general = Fk.generals[g_name]
      return true
    end)
    if #same_generals > 0 then
      table.insert(allgenerals, table.random(same_generals))
    end
  end
  if #allgenerals == 0 then return false end  --判空这一块./（但是真的会没武将可用吗。。）
  local choices_draw, skills_draw = {}, {}   --词条1的所有武将及技能
  local choices_damage, skills_damage = {}, {}   --词条2的所有武将及技能
  local choices_view, skills_view = {}, {}   --词条3的所有武将及技能
  local total_choices = {}   --3个词条的所有武将
  local total_skills = {}   --3个词条的所有技能
  for _, general_name in ipairs(allgenerals) do   --从所有武将中筛选所有可选武将
    local general = Fk.generals[general_name]
    local total = table.filter(general:getSkillNameList(true), function(s)
      return (string.find(Fk:getDescription(s, "zh_CN"), pattern1) ~= nil) or
      (string.find(Fk:getDescription(s, "zh_CN"), pattern2) ~= nil) or
      (string.find(Fk:getDescription(s, "zh_CN"), pattern3) ~= nil)
    end)
    if #total > 0 then
      table.insert(total_choices, general_name)
      for _, s in ipairs(total) do
        table.insertIfNeed(total_skills, s)   --那么问题来了，这里的IfNeed加不加有区别吗。。
      end
    end
  end
  local generals = {}  --可选武将的……初始化？
  local has_generals = table.random(total_choices, 3)  --保底3个词条武将
  local total_randomchoices = {}  --随机的所有武将
  local has_randomgenerals = {}  --3个保底武将之外的随机武将
  for _, general_name in ipairs(has_generals) do  --将3个词条武将加入到可选武将
    table.insert(generals, general_name)
  end
  if number > 3 then  --4上限福利，随机武将的筛选
    for _, general_name in ipairs(allgenerals) do   --从所有武将中排除保底武将
      if not table.contains(has_generals, general_name) then
        table.insert(total_randomchoices, general_name)
      end
    end
    has_randomgenerals = table.random(total_randomchoices, number-3)  --真·随机武将
    for _, general_name in ipairs(has_randomgenerals) do   --将随机武将加入到可选武将
      table.insert(generals, general_name)
    end
  end
  for _, general_name in ipairs(generals) do  --依次把可选武将及他们各自的技能分类进表里
    local general = Fk.generals[general_name]
    local to_draw = table.filter(general:getSkillNameList(true), function(s) --词条1武将的技能
      return (string.find(Fk:getDescription(s, "zh_CN"), pattern1) ~= nil)
    end)
    local to_damage = table.filter(general:getSkillNameList(true), function(s) --词条2武将的技能
      return (string.find(Fk:getDescription(s, "zh_CN"), pattern2) ~= nil)
    end)
    local to_view = table.filter(general:getSkillNameList(true), function(s) --词条3武将的技能
      return (string.find(Fk:getDescription(s, "zh_CN"), pattern3) ~= nil)
    end)
    if #to_draw > 0 then  --词条1武将及其技能的录入
      table.insert(choices_draw, general_name)
      for _, s in ipairs(to_draw) do
        table.insertIfNeed(skills_draw, s)
      end
    end
    if #to_damage > 0 then  --词条2武将及其技能的录入
      table.insert(choices_damage, general_name)
      for _, s in ipairs(to_damage) do
        table.insertIfNeed(skills_damage, s)
      end
    end
    if #to_view > 0 then  --词条3武将及其技能的录入
      table.insert(choices_view, general_name)
      for _, s in ipairs(to_view) do
        table.insertIfNeed(skills_view, s)
      end
    end
  end
  local getskills = {} -- 将要获得的技能
  local togeneral = {} -- 武租哥没有原画，这是他随机变身的武将列表
  local generals_tran = {}  -- 武将的翻译表，用来把可选武将显示在战报里
  for _, g in ipairs(generals) do  --录入武将翻译
    table.insert(generals_tran, Fk:translate(g))
  end
  local allpattern = {}  --所有词条，当然也是为了可以显示在战报里
  table.insert(allpattern, pattern1)  --词条1录入到所有词条
  table.insert(allpattern, pattern2)  --词条2录入到所有词条
  table.insert(allpattern, pattern3)  --词条3录入到所有词条
  room:sendLog({type = "#zuhao_log", from = player.id, arg = table.concat(allpattern, "、"), arg2 = table.concat(generals_tran, "、"),})  --发送战报
  local draw = room:askToCustomDialog( player, {  --询问选择词条1的正确武将
    skill_name = Skill,  --技能名
    qml_path = "packages/huixiangkill/qml/HX__ChooseGeneralsAndChoiceBox.qml",  --调用的框的路径，这里用的是改的经典的选武将的框
    extra_data = {  --词条2和词条3同理
      generals, --可选武将
      {"OK"},  --选项按钮
      "请选择任意个武将,若被选武将的某个技能的描述中包含“"..pattern1.."”,<br/>则你本轮获得此技能;若被选武将无此类技能，你减1点体力上限",  --提示信息
      {"Cancel"},  --取消按钮？反正如果只写{}的话会只有确定按钮
      1, --最小选择数
      number,  --最大选择数
    },
  })
  -- if draw == "" then return end  --烧条直接return是不行的，优化成正常的进行下一个选择才对，下面的同理
  local draw_true = {}  --选对的词条1武将
  local truegeneral_1 = {}  --选对的词条1武将的翻译
  local falsegeneral_1 = {}  --选错的词条1武将的翻译
  if draw ~= "" then
    local reply = draw
    draw = reply.cards
    for _, general_name in ipairs(draw) do
      if table.contains(choices_draw, general_name) then
        table.insert(draw_true, general_name)   --录入选对的词条1武将
        table.insert(truegeneral_1, Fk:translate(general_name))  --录入选对的词条1武将的翻译
      else
        table.insert(falsegeneral_1, Fk:translate(general_name))  --录入选错的词条1武将的翻译
      end
    end
    generals = table.filter(generals, function(g) return not table.contains(draw, g) end)  --将词条1的武将筛出去
    for _, general_name in ipairs(draw_true) do  --将选对的词条1武将的技能加入到获得技能表
      local general = Fk.generals[general_name]
      for _, getskill in ipairs(general:getSkillNameList(true)) do
        if table.contains(skills_draw, getskill) then
          table.insertIfNeed(getskills, getskill)  --录入词条1中可获得的技能
          table.insertIfNeed(togeneral, general_name)  --录入词条1中可变身的武将
        end
      end
    end
  end
  local draw_false = math.max(0, #draw - #draw_true)  --词条1选错的武将数
  local damage = room:askToCustomDialog( player, {  --询问选择词条2的正确武将
    skill_name = Skill,
    qml_path = "packages/huixiangkill/qml/HX__ChooseGeneralsAndChoiceBox.qml",
    extra_data = {
      generals,
      {"OK"},
      "请选择任意个武将,若被选武将的某个技能的描述中包含“"..pattern2.."”,<br/>则你本轮获得此技能;若被选武将无此类技能，你减1点体力上限",
      {"Cancel"},
      1,
      number,
    },
  })
  local damage_true = {}  --选对的词条2武将
  local truegeneral_2 = {}  --选对的词条2武将的翻译
  local falsegeneral_2 = {}  --选错的词条2武将的翻译
  if damage ~= "" then
    local reply2 = damage
    damage = reply2.cards
    for _, general_name in ipairs(damage) do  
      if table.contains(choices_damage, general_name) then
        table.insert(damage_true, general_name)  --录入选对的词条2武将
        table.insert(truegeneral_2, Fk:translate(general_name))  --录入选对的词条2武将的翻译
      else
        table.insert(falsegeneral_2, Fk:translate(general_name))  --录入选错的词条2武将的翻译
      end
    end
    generals = table.filter(generals, function(g) return not table.contains(damage, g) end)  --将词条2的武将筛出去
    for _, general_name in ipairs(damage_true) do
      local general = Fk.generals[general_name]
      for _, getskill in ipairs(general:getSkillNameList(true)) do
        if table.contains(skills_damage, getskill) then
          table.insertIfNeed(getskills, getskill)  --录入词条2中可获得的技能
          table.insertIfNeed(togeneral, general_name)  --录入词条2中可变身的武将
        end
      end
    end
  end
  local damage_false = math.max(0, #damage - #damage_true)  --词条2选错的武将数
  local view = room:askToCustomDialog( player, {  --询问选择词条3的正确武将
    skill_name = Skill,
    qml_path = "packages/huixiangkill/qml/HX__ChooseGeneralsAndChoiceBox.qml",
    extra_data = {
      generals,
      {"OK"},
      "请选择任意个武将,若被选武将的某个技能的描述中包含“"..pattern3.."”,<br/>则你本轮获得此技能;若被选武将无此类技能，你减1点体力上限",
      {"Cancel"},
      1,
      number,
    },
  })
  local view_true = {}  --选对的词条3武将
  local truegeneral_3 = {}  --选对的词条3武将的翻译
  local falsegeneral_3 = {}  --选错的词条3武将的翻译
  if view ~= "" then
    local reply3 = view
    view = reply3.cards
    for _, general_name in ipairs(view) do
      if table.contains(choices_view, general_name) then
        table.insert(view_true, general_name)  --录入选对的词条3武将
        table.insert(truegeneral_3, Fk:translate(general_name))  --录入选对的词条3武将的翻译
      else
        table.insert(falsegeneral_3, Fk:translate(general_name))  --录入选错的词条3武将的翻译
      end
    end
    for _, general_name in ipairs(view_true) do
      local general = Fk.generals[general_name]
      for _, getskill in ipairs(general:getSkillNameList(true)) do
        if table.contains(skills_view, getskill) then
          table.insertIfNeed(getskills, getskill)  --录入词条3中可获得的技能
          table.insertIfNeed(togeneral, general_name)  --录入词条3中可变身的武将
        end
      end
    end
  end
  local view_false = math.max(0, #view - #view_true)  --词条3选错的武将数
  local maxhplost = draw_false + damage_false + view_false  --选错的武将总数，用于体力上限减少及战报显示
  if #getskills > 0 then
    room:sendLog({type = "#zuhao_true_log", from = player.id, --发送选对的武将
    arg = table.concat(truegeneral_1, "、") ,
    arg2 = table.concat(truegeneral_2, "、") ,
    arg3 = table.concat(truegeneral_3, "、") })
    if player.general == "hxqunyou__wuzuge" or player.deputyGeneral == "hxqunyou__wuzuge" or player:hasSkill("hx__zuhao", true) then  --武租哥的变身
      local tochange = table.random(togeneral, 2)  --控制随机性
      player.general = tochange[1]
      if #tochange > 1 then
        player.deputyGeneral = tochange[2]
        room:broadcastProperty(player, "deputyGeneral")
      end
      room:broadcastProperty(player, "general")
    end
    local mark = player:getTableMark("@[:]zuhao_skills-round") or {}  --租号技能显示
    for _, g in ipairs(getskills) do
      table.insertIfNeed(mark, g)  --录入技能
    end
    room:setPlayerMark(player, "@[:]zuhao_skills-round", mark)  --设置可点开查看的标记，就是技能显示
    room:handleAddLoseSkills(player, table.concat(getskills, "|"))  --获得技能
    local round_event = room.logic:getCurrentEvent():findParent(GameEvent.Round)  --只获得一轮
    if round_event ~= nil then
      round_event:addCleaner(function()
        room:handleAddLoseSkills(player, "-"..table.concat(getskills, "|-"))  --移去技能
      end)
    end
  end
  if maxhplost > 0 then
    room:sendLog({type = "#zuhao_false_log", from = player.id, --发送选错的武将
    arg = table.concat(falsegeneral_1, "、") ,
    arg2 = table.concat(falsegeneral_2, "、") ,
    arg3 = table.concat(falsegeneral_3, "、") })
    room:sendLog({type = "#zuhao_falsenum_log", from = player.id, --发送要减少的体力上限
    arg = maxhplost })
    for i = 1, maxhplost do
      room:changeMaxHp(player, -1)  --减上限
    end
  end
end



-- 有X%的概率返回1 = if HasRandom(X) then return 1 end
---@param X? integer @ x的最小值，默认为1
function hxfs.HasRandom(X)
  local randomNumber = math.random(1, 100)
  return randomNumber <= X
end


---下面两个函数为 表情包柴郡 的技能的主要逻辑

---分别选择要移去的表情包和要给予的表情包，执行完后，返回的toremove是玩家要移除的两个表情包构成的表
---@param room Room 房间
---@param player ServerPlayer 玩家
---@param mark table 玩家当前的表情包
---@param skill_name string 技能名
function hxfs.ChuanDi(room, player, mark, skill_name)
  local toremove = {}
  local result = room:askToCustomDialog( player, {
    skill_name = skill_name,
    qml_path = "packages/utility/qml/ChooseGeneralsAndChoiceBox.qml",
    extra_data = {
      player:getTableMark("@&hx__moyin_emoji"),
      {"OK"},
      "#hx__chuandi-remove",
      {},
      1,
      1,
    },
  })
  if result ~= "" then
    local reply = result
    table.insert(toremove, reply.cards[1])
  else
    table.insert(toremove, table.random(mark))
  end
  table.removeOne(mark, toremove[1])
  if #mark > 1 then
    result = room:askToCustomDialog( player, {
      skill_name = skill_name,
      qml_path = "packages/utility/qml/ChooseGeneralsAndChoiceBox.qml",
      extra_data = {
        mark,
        {"OK"},
        "#hx__chuandi-give",
        {},
        1,
        1,
      },
    })
    if result ~= "" then
      local reply = result
      table.insert(toremove, 2, reply.cards[1])
    else
      table.insert(toremove, 2, table.random(mark))
    end
  else
    table.insert(toremove, 2, table.random(mark))
  end
  table.removeOne(mark, toremove[2])
  return toremove
end


---on_use部分，更新标记、切换目标武将图、玩家摸两张牌
---@param room Room 房间
---@param player ServerPlayer 玩家
---@param mark table 玩家当前的表情包
---@param to ServerPlayer 接收表情包的玩家
---@param toremove table 要移除的表情包
---@param skill_name string 技能名
function hxfs.AfterChuanDi(room, player, mark, to, toremove, skill_name)
  room:setPlayerMark(player, "@&hx__moyin_emoji", mark)
  room:addTableMark(to, "@&hx__moyin_emoji", toremove[2])
  to.general = toremove[2]
  to.deputyGeneral = ""
  room:broadcastProperty(to, "general")
  room:broadcastProperty(to, "deputyGeneral")
  player:drawCards(2, skill_name)
end


---上面两个函数为 表情包柴郡 的技能的主要逻辑


--————————————忆者模式——————————————————



--- 获得当前房间中的忆者，其实就是找内奸，同时也要在对应的tag里
---@param room Room @ 房间
---@return ServerPlayer[]? @ 忆者列表
function hxfs.getyizhe(room)
  local allyizhe = room:getTag("hx__simulator_allyizhe")
  local players = {}
  for _, p in ipairs(room.players) do
    if p.role == "renegade" and table.contains(allyizhe, p) then
      table.insert(players, p)
    end
  end

  return players
end

--- 判断一名角色是否是忆者
---@param room Room @ 房间
---@param player ServerPlayer @ 角色
---@return boolean @ 是否是忆者
function hxfs.Isyizhe(room, player)
  local allyizhe = room:getTag("hx__simulator_allyizhe")
  if player.role == "renegade" and table.contains(allyizhe, player) then
    return true
  end
  return false
end


--————————————忆者模式——————————————————


---以下逻辑来自水天一色大佬


--获取玩家模式胜负场
---@param room Room @ 房间
---@param player ServerPlayer @ 玩家
---@param mode string @ 模式
---@return table @ 总场数和胜场
function hxfs.GetModeData(room, player, mode)
  local modename = room.settings.gameMode
  room.settings.gameMode = mode
  room.room:updatePlayerWinRate(player.id, mode, "rebel", 0)
  local data = player._splayer:getGameData()
  local tot, win = data:at(0), data:at(1)
  local ret = {tot, win}
  room.settings.gameMode = modename --恢复
  return ret
end

--改变玩家的财产
---@param room Room @ 房间
---@param mode string @ 财产类型，目前分别为"hx_1v2_jindou"和"hx_1v2__ling"
---@param player ServerPlayer @ 玩家
---@param num integer @ 改变量
function hxfs.ChangePlayerMoney(room, mode, player, num)
  if player.id <= 0 then return false end
  if room.settings.enableFreeAssign and table.find(room.players, function (p) return p.id <= 0 end) then return false end
  local sdata = hxfs.GetModeData(room, player, mode)
  local total, win = sdata[1], sdata[2]
  local lose = total - win
  local now = win - lose
  if (now < 0 and num < 0) then return false end
  local addorlose = 1
  if num > 0 then
    addorlose = 1
  elseif num < 0 then
    addorlose = 2
  end
  num = math.abs(num)
  if num == 0 then return end
  room:sendLog{ type = "#hx_1v2_changeMoney", toast = true }
  for i = 1, num do
    room.room:updatePlayerWinRate(player.id, mode, "lord", addorlose)
  end
  room:sendLog{ type = "#hx_1v2_changeMoneyOver", toast = true }
end

--初始化金豆并更新玩家的财产，返回财产数量
---@param room Room @ 房间
---@param mode string @ 财产类型，目前分别为"hx_1v2_jindou"和"hx_1v2__ling"
---@param player ServerPlayer @ 玩家
function hxfs.GetPlayerMoney(room, mode, player)
  if player.id <= 0 then return false end
  local sdata = hxfs.GetModeData(room, player, mode)
  local total, win = sdata[1], sdata[2]
  if total == 0 and win == 0 and mode == "hx_1v2_jindou" then
    --初始化金豆
    room:sendLog{ type = "#hx_1v2_initMoney", toast = true }
    hxfs.ChangePlayerMoney(room, mode, player, 1000)
  end
  local data = hxfs.GetModeData(room, player, mode)
  total, win = data[1], data[2]
  local lose = total - win
  local num = win - lose
  room:setPlayerMark(player, "@!!"..mode, num)
  if num > 0 and player.id > 0 then
    room:setPlayerMark(player, "@[hxjindou]"..mode, 1)
  end
  return num
end


---以上逻辑来自水天一色大佬



return hxfs